#include "protocol.h"

static Protocol_Parameter_s protocol_params;
static Protocol_Config_s protocol_instance;
uint8_t Check_Sum(unsigned char Count_Number, unsigned char mode, uint8_t *data)
{
    unsigned char check_sum = 0, k;

    if (mode == 0) // Receive data mode //接收数据模式
    {
        for (k = 0; k < Count_Number; k++)
        {
            check_sum = check_sum ^ data[k]; // By bit or by bit //按位异或
        }
    }
    if (mode == 1) // Send data mode //发送数据模式
    {
        for (k = 0; k < Count_Number; k++)
        {
            check_sum = check_sum ^ data[k]; // By bit or by bit //按位异或
        }
    }
    return check_sum; // Returns the bitwise XOR result //返回按位异或结果
}

Protocol_Config_s *ProtocolInit(UART_HandleTypeDef *_instance)
{
    protocol_params.header[0] = FRAME_HEADER;
    protocol_params.header[1] = 0;
    protocol_params.header[2] = 0;
    protocol_params.tail[0] = FRAME_TAIL;
    USART_Init_Config_s usart_config = {
        .recv_buff_size = 11,
        .usart_handle = _instance,
        .module_callback = Protocol_Recv,
    };
    protocol_params.instance = USARTRegister(&usart_config);
    protocol_instance.protocol_params = &protocol_params;
    return &protocol_instance;
}

void Protocol_Send(uint8_t *data, uint8_t len)
{
    uint8_t send_buf[256] = {0};
    for (uint8_t i = 0; i < FRAME_HEADER_LEN; i++)
        send_buf[i] = protocol_params.header[i];

    for (int i = 0; i < len; i++)
    {
        send_buf[3 + i] = data[i];
    }
    send_buf[3 + len] = Check_Sum(len + 3, 1, send_buf);
    send_buf[3 + len + 1] = protocol_params.tail[0];

    USARTSend(protocol_params.instance, send_buf, len + 5, USART_TRANSFER_BLOCKING);
}

void Protocol_Recv()
{
    for (uint8_t i = 0; i < FRAME_HEADER_LEN; i++)
    {
        if (protocol_params.instance->recv_buff[i] != protocol_params.header[i])
            return;
    }
    
    if (protocol_params.instance->recv_buff[9] != Check_Sum(protocol_params.instance->recv_buff_size - 2, 0, protocol_params.instance->recv_buff))
        return;

    if (protocol_params.instance->recv_buff[10] != protocol_params.tail[0])
        return;
    
    for (uint8_t i = 0; i < 6; i++)
    {
        protocol_instance.data[i] = protocol_params.instance->recv_buff[i + 3];
    }
}
